﻿using Windows.UI.Xaml;
using Windows.UI.Xaml.Input;
using Microsoft.Toolkit.Uwp;
using Microsoft.Toolkit.Uwp.UI;

namespace Sidvall.UI.Uwp.Controls
{
    public sealed partial class RadioButtonListControl
    {
        #region Public Members

        #region DisplayMemberPath

        public static readonly DependencyProperty DisplayMemberPathProperty = DependencyProperty.Register(nameof(DisplayMemberPath), typeof(string), typeof(RadioButtonListControl),
            new PropertyMetadata(null, null));
        public string DisplayMemberPath
        {
            get
            {
                return GetValue(DisplayMemberPathProperty) as string;
            }
            set
            {
                SetValue(DisplayMemberPathProperty, value);
            }
        }

        #endregion
        #region GroupName

        public static readonly DependencyProperty GroupNameProperty = DependencyProperty.Register(nameof(GroupName), typeof(string), typeof(RadioButtonListControl),
            new PropertyMetadata(null, null));
        public string GroupName
        {
            get
            {
                return GetValue(GroupNameProperty) as string;
            }
            set
            {
                SetValue(GroupNameProperty, value);
            }
        }

        #endregion
        #region ItemMargin

        public static readonly DependencyProperty ButtonMarginProperty = DependencyProperty.Register(nameof(ItemMargin), typeof(Thickness), typeof(RadioButtonListControl),
            new PropertyMetadata(new Thickness(8, 0, 0, 0), null));
        public Thickness ItemMargin
        {
            get
            {
                return (Thickness)GetValue(ButtonMarginProperty);
            }
            set
            {
                SetValue(ButtonMarginProperty, value);
            }
        }

        #endregion
        #region ItemsSource

        public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(nameof(ItemsSource), typeof(System.Collections.IEnumerable), typeof(RadioButtonListControl),
            new PropertyMetadata(null, OnItemsSourcePropertyChanged));
        public System.Collections.IEnumerable ItemsSource
        {
            get
            {
                return GetValue(ItemsSourceProperty) as System.Collections.IEnumerable;
            }
            set
            {
                SetValue(ItemsSourceProperty, value);
            }
        }

        #endregion
        #region Orientation

        public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(nameof(Orientation), typeof(Windows.UI.Xaml.Controls.Orientation), typeof(RadioButtonListControl),
            new PropertyMetadata(Windows.UI.Xaml.Controls.Orientation.Vertical, null));
        public Windows.UI.Xaml.Controls.Orientation Orientation
        {
            get
            {
                return (Windows.UI.Xaml.Controls.Orientation)GetValue(OrientationProperty);
            }
            set
            {
                SetValue(OrientationProperty, value);
            }
        }

        #endregion
        #region SelectedValue

        public static readonly DependencyProperty SelectedValueProperty = DependencyProperty.Register(nameof(SelectedValue), typeof(object), typeof(RadioButtonListControl),
            new PropertyMetadata(null, OnSelectedValuePropertyChanged));
        public object SelectedValue
        {
            get
            {
                return GetValue(SelectedValueProperty);
            }
            set
            {
                SetValue(SelectedValueProperty, value);
            }
        }

        #endregion
        #region SelectedValuePath

        public static readonly DependencyProperty SelectedValuePathProperty = DependencyProperty.Register(nameof(SelectedValuePath), typeof(string), typeof(RadioButtonListControl),
            new PropertyMetadata(null, null));
        public string SelectedValuePath
        {
            get
            {
                return GetValue(SelectedValuePathProperty) as string;
            }
            set
            {
                SetValue(SelectedValuePathProperty, value);
            }
        }

        #endregion

        #region OnItemsSourcePropertyChanged

        private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var parent = d as RadioButtonListControl;
            if (parent == null)
                return;

            parent.StackPanel.Children.Clear();
            if (parent.ItemsSource != null)
            {
                var count = 0;
                foreach (var item in parent.ItemsSource)
                {
                    var radioButton = new Windows.UI.Xaml.Controls.RadioButton()
                    {
                        GroupName = parent.GroupName,
                        Content = Sidvall.SystemContext.Current.CodeManager.GetPropertyValue(item, parent.DisplayMemberPath),
                        Tag = Sidvall.SystemContext.Current.CodeManager.GetPropertyValue(item, parent.SelectedValuePath),
                    };
                    if (count > 0)
                        radioButton.Margin = parent.ItemMargin;
                    if (radioButton.Tag.Equals(parent.SelectedValue))
                        radioButton.IsChecked = true;
                    parent.StackPanel.Children.Add(radioButton);
                    count += 1;
                }
            }
        }

        #endregion
        #region OnSelectedValuePropertyChanged

        private static void OnSelectedValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var parent = d as RadioButtonListControl;
            if (parent == null)
                return;

            parent.EventsEnabled = false;
            if (parent.StackPanel.Children != null)
            {
                foreach (var item in parent.StackPanel.Children)
                {
                    var radioButton = item as Windows.UI.Xaml.Controls.RadioButton;
                    if (radioButton != null)
                    {
                        if (radioButton.Tag.Equals(parent.SelectedValue))
                            radioButton.IsChecked = true;
                        else
                            radioButton.IsChecked = false;
                    }
                }
            }
            parent.EventsEnabled = true;
        }

        #endregion

        #endregion
        #region Private Members

        private bool EventsEnabled = true;

        #endregion
        #region Events

        #region OnButtonChecked

        private void OnButtonChecked(object sender, TappedRoutedEventArgs e)
        {
            if (!this.EventsEnabled)
                return;

            var element = e.OriginalSource as FrameworkElement;
            if (element == null)
                return;
            var radioButton = element.FindVisualAscendant<Windows.UI.Xaml.Controls.RadioButton>();
            this.SelectedValue = radioButton.Tag;
        }

        #endregion

        #endregion
        #region Constructors

        public RadioButtonListControl()
        {
            this.InitializeComponent();

            this.StackPanel.AddHandler(UIElement.TappedEvent, new Windows.UI.Xaml.Input.TappedEventHandler(OnButtonChecked), false);
        }

        #endregion
    }
}
